package com.servicelive.service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.servicelivedb.ServiceliveDB;
import com.servicelivedb.data.Block;
import com.servicelivedb.data.Customer;
import com.servicelivedb.data.CustomerProject;
import com.servicelivedb.data.Door;
import com.servicelivedb.data.Project;
import com.wavemaker.runtime.RuntimeAccess;
import com.wavemaker.runtime.javaservice.JavaServiceSuperClass;
import com.wavemaker.runtime.service.annotations.ExposeToClient;

@ExposeToClient
public class ServiceLiveService extends JavaServiceSuperClass {
	public ServiceLiveService() {
		super(INFO);
	}

	public String cleanUpProject(Integer projectId) {

		return null;
	}

	public UserDetails retrieveUserDetails(String email, String password,
			String projectName) {

		ServiceliveDB db = (ServiceliveDB) RuntimeAccess.getInstance()
				.getServiceBean("serviceliveDB");
		UserDetails result = new UserDetails();
		try {
			log(INFO, "####### email= " + email);
			log(INFO, "####### password= " + password);
			log(INFO, "####### projectName= " + projectName);
			db.begin();

			Session session = db.getDataServiceManager().getSession();

			Query query = session
					.createQuery("from Customer user where lower(user.email)= :email and user.password= :password and active=true and user.project.projectName= :projectName ");
			query.setString("email", email.toLowerCase());
			query.setString("password", password);
			query.setString("projectName", projectName);
			List userList = query.list();

			if (userList != null && !userList.isEmpty()) {

				Customer user = (Customer) userList.get(0);
				System.out.println("$$$$$$$$ user found ::" + user.getName());
				result.setCustomerId(user.getCustomerId());
				result.setEmail(user.getEmail());
				result.setAuthenticated(true);
				result.setName(user.getName());
				result.setRoles(user.getType());
				result.setMessage("User Logged in successfully");
				result.setProjectId(user.getProject().getProjectId());
				/*
				 * for (CustomerProject cp : user.getCustomerProjects()) { if
				 * (cp.getProject().getActive()) {
				 * result.setProjectId(cp.getProject().getProjectId()); } }
				 */

			} else {
				System.out.println("User not found in the Project");
				result.setMessage("User not found in the Project");
				result.setAuthenticated(false);

			}

			log(INFO, "Returning " + result);

			db.commit();
		} catch (Exception e) {
			db.rollback();

			result.setMessage("User not found in the Project");
			result.setAuthenticated(false);
			log(ERROR, "Error in retrieveUserDetails;user=" + email
					+ ";password=" + password, e);
		}
		return result;

	}

	public Project searchProjectByName(String projectName) {

		ServiceliveDB db = (ServiceliveDB) RuntimeAccess.getInstance()
				.getServiceBean("serviceliveDB");
		Project project = new Project();
		try {
			log(INFO, "###############projectName= " + projectName);

			db.begin();

			Session session = db.getDataServiceManager().getSession();

			Query query = session
					.createQuery(" from Project project where project.projectName= :projectName and project.active=true");
			query.setString("projectName", projectName);

			Project projectDB = (Project) query.uniqueResult();
			project.setProjectId(projectDB.getProjectId());
			project.setProjectName(projectDB.getProjectName());

			log(INFO, "Returning " + project);

			db.commit();
		} catch (Exception e) {
			db.rollback();

			log(ERROR, "Error during registration", e);

		}

		return project;

	}

	public String register(Customer customer) throws Exception {
		String result = null;

		ServiceliveDB db = (ServiceliveDB) RuntimeAccess.getInstance()
				.getServiceBean("serviceliveDB");

		try {

			// log(INFO, "activationCode=" + activationCode);
			log(INFO, "email=" + customer.getEmail().toLowerCase());

			db.begin();

			Session session = db.getDataServiceManager().getSession();
			// TODO: validations
			Criteria criteria = session.createCriteria(Customer.class);
			criteria.add(Restrictions.eq("email",
					customer.getEmail().toLowerCase()).ignoreCase());
			List results = criteria.list();
			if (results != null && !results.isEmpty()) {
				log(ERROR,
						"Email id already in use.Please use different id or login using the same");
				throw new Exception(
						"Email id already in use.Please use different id or login using the same");
			}

			Query query = session
					.createQuery(" from Block block where lower(block.blockName)= :blockName and block.project.projectName= :projectName");
			query.setString("blockName", customer.getBlock().getBlockName()
					.toLowerCase());
			query.setString("projectName", customer.getProject()
					.getProjectName());
			List<Block> blocks = query.list();
			if (blocks == null || blocks.isEmpty()) {
				log(ERROR, "Entered Block does not exist in the Project.");
				throw new Exception(
						"Entered Block does not exist in the Project.");
			} else {

				customer.setBlock(blocks.get(0));
			}

			query = session
					.createQuery(" from Door door where lower(door.doorName)= :doorName and lower(door.block.blockName)= :blockName and door.block.project.projectName= :projectName");
			query.setString("doorName", customer.getDoor().getDoorName()
					.toLowerCase());
			query.setString("blockName", customer.getBlock().getBlockName()
					.toLowerCase());
			query.setString("projectName", customer.getProject()
					.getProjectName());
			List<Door> doors = query.list();
			if (doors == null || doors.isEmpty()) {
				log(ERROR, "Entered Door does not exist in the Block.");
				throw new Exception("Entered Door does not exist in the Block.");
			} else {

				customer.setDoor(doors.get(0));
			}

			query = session
					.createQuery(" from Project project where project.projectName= :projectName ");
			query.setString("projectName", customer.getProject()
					.getProjectName());
			Project project = (Project) query.uniqueResult();
			customer.setEmail(customer.getEmail().toLowerCase());
			customer.setProject(project);
			customer.setUpdatedBy("SYS");
			Calendar startingCalendar = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
			customer.setUpdatedDt(startingCalendar.getTime());
			customer.setActive(true);
			customer.setType("CUSTOMER");
			session.save(customer);

			CustomerProject cp = new CustomerProject();
			cp.setActive(true);
			cp.setCustomer(customer);
			cp.setProject(project);

			session.save(cp);

			System.out.println("proj name::"
					+ customer.getProject().getProjectName());
			System.out.println("customer::" + customer.getName());

			log(INFO, "Returning *********************" + result);

			db.commit();
			result = "User registration successfull";
		} catch (Exception e) {
			db.rollback();
			log(ERROR, "Error during registration", e);
			throw e;
		}
		return result;
	}

	public String registerVendor(Customer customer, Integer activationCode,
			Boolean isVendor) throws Exception {
		String result = null;

		ServiceliveDB db = (ServiceliveDB) RuntimeAccess.getInstance()
				.getServiceBean("serviceliveDB");

		try {

			db.begin();

			Session session = db.getDataServiceManager().getSession();
			// TODO: validations
			Criteria criteria = session.createCriteria(Customer.class);
			criteria.add(Restrictions.eq("email", customer.getEmail()));
			List results = criteria.list();
			if (results != null && !results.isEmpty()) {

				throw new Exception(
						"Email id already in use.Please use different id or login using the same");
			}

			Query query = session
					.createQuery(" from Project project where project.projectId= :projectId ");
			query.setInteger("projectId", activationCode);
			Project project = (Project) query.uniqueResult();

			customer.setEmail(customer.getEmail().toLowerCase());
			customer.setUpdatedBy("SYS");
			Calendar startingCalendar = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
			customer.setUpdatedDt(startingCalendar.getTime());
			customer.setActive(true);
			if (isVendor) {
				customer.setType("VENDOR");
			} else {
				customer.setType("CUSTOMER");

				Block block = (Block) session.get(Block.class, customer
						.getBlock().getBlockId());
				customer.setBlock(block);

				Door door = (Door) session.get(Door.class, customer.getDoor()
						.getDoorId());
				customer.setDoor(door);
			}

			customer.setProject(project);

			session.save(customer);

			CustomerProject cp = new CustomerProject();
			cp.setActive(true);
			cp.setCustomer(customer);
			cp.setProject(project);

			// cp.setBlock(customer.getBlock());
			// cp.setDoorNo(customer.getDoor());

			session.save(cp);

			log(INFO, "Starting sample operation");

			System.out.println("activationCode::" + activationCode);
			System.out.println("customer::" + customer.getName());

			result = "Hello World";
			log(INFO, "Returning " + result);

			db.commit();
		} catch (Exception e) {
			db.rollback();
			log(ERROR, "The sample java service operation has failed", e);
			throw e;
		}
		return result;
	}

	public Block getBlock(Session session, String blockName, Integer projectId) {
		Block block = null;

		try {
			Query query = session
					.createQuery(" from Block block where block.blockName= :blockName and block.project.projectId= :projectId");
			query.setString("blockName", blockName);
			query.setInteger("projectId", projectId);
			block = (Block) query.uniqueResult();
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return block;

	}

	public Door getDoor(Session session, Integer blockId, String doorName,
			Integer projectId) {
		Door door = null;

		try {
			Query query = session
					.createQuery(" from Door door where door.doorName= :doorName and door.block.blockId=:blockId and door.block.project.projectId= :projectId");
			query.setString("doorName", doorName);
			query.setInteger("blockId", blockId);
			query.setInteger("projectId", projectId);
			door = (Door) query.uniqueResult();

		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return door;

	}
	public Boolean getShoptimings(Integer vendorId) {
		Boolean result = false;
		ServiceliveDB db = (ServiceliveDB) RuntimeAccess.getInstance()
				.getServiceBean("serviceliveDB");	
			
		try {
			db.begin();

			Session session = db.getDataServiceManager().getSession();
			System.out.println("vendor ID @@@@"+vendorId);
			Query query = session
					.createQuery(" from Customer customer where customer.customerId= :vendorId ");
			query.setInteger("vendorId", vendorId);
			
			Customer vendor = (Customer) query.uniqueResult();
			
			String shopTime=vendor.getShop_time();
			if(shopTime!=null && !shopTime.isEmpty())
			{
				List<String> opencloseTime = Arrays.asList(shopTime.split(";"));
				if(opencloseTime!=null && !opencloseTime.isEmpty())
				{
					for(String shoptimes : opencloseTime)
					{
						String [] items = shoptimes.split(",");
						String openTime=items[0];
						String closeTime=items[1];					

						System.out.println("openTime @@"+openTime);
						System.out.println("closeTime @@"+closeTime);
						
						
					    SimpleDateFormat formatter = new SimpleDateFormat("h:mm a");
						
						
						try {
							Calendar startingCalendar = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
							startingCalendar.set(Calendar.YEAR, 0);
							startingCalendar.set(Calendar.MONTH, 0);
							startingCalendar.set(Calendar.DAY_OF_MONTH, 0);
							
							Calendar calendar1 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
							calendar1.setTime(formatter.parse(openTime));
							calendar1.set(Calendar.YEAR, 0);
							calendar1.set(Calendar.MONTH, 0);
							calendar1.set(Calendar.DAY_OF_MONTH, 0);							

							
							Calendar calendar2 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
							calendar2.setTime(formatter.parse(closeTime));
							calendar2.set(Calendar.YEAR, 0);
							calendar2.set(Calendar.MONTH, 0);
							calendar2.set(Calendar.DAY_OF_MONTH, 0);
							

							if (startingCalendar.getTime().after(calendar1.getTime()) && startingCalendar.getTime().before(calendar2.getTime())) 
							{
								System.out.println("Time is in between..");
								result=true;
							}
						} catch (ParseException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
					}
				}
			
			}else{
				result=true;
			}
			db.commit();
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			db.rollback();
			e.printStackTrace();
		}
System.out.println("RESULT @@"+result);
		return result;

	}
	public String forgotPassword(String email) throws Exception {
		String result = null;

		MailSenderService mail = (MailSenderService) RuntimeAccess
				.getInstance().getServiceBean("MailSenderService");

		try {
			return mail.sendPasswordinEmail(email);

		} catch (Exception e) {

			log(ERROR, "Error during forgotPassword", e);
			return "Error during forgotPassword";

		}

	}

	public class UserDetails {

		private Integer customerId;
		private String name;
		private boolean isAuthenticated;
		private String roles;
		private String message;
		private String email;
		private Integer projectId;
		private String type;

		public Integer getProjectId() {
			return projectId;
		}

		public void setProjectId(Integer projectId) {
			this.projectId = projectId;
		}

		public Integer getCustomerId() {
			return customerId;
		}

		public void setCustomerId(Integer customerId) {
			this.customerId = customerId;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public boolean isAuthenticated() {
			return isAuthenticated;
		}

		public void setAuthenticated(boolean isAuthenticated) {
			this.isAuthenticated = isAuthenticated;
		}

		public String getRoles() {
			return roles;
		}

		public void setRoles(String roles) {
			this.roles = roles;
		}

		public String getEmail() {
			return email;
		}

		public void setEmail(String email) {
			this.email = email;
		}

		public String getMessage() {
			return message;
		}

		public void setMessage(String message) {
			this.message = message;
		}

		public String getType() {
			return type;
		}

		public void setType(String type) {
			this.type = type;
		}

	}
	
}
